#define xuser mixc::powerful_cat
#include"io/dir.hpp"
#include"io/file.hpp"
#include"io/tty.hpp"
#include"interface/seqptr.hpp"
#include"lang/cxx/count_of.hpp"
#include"lang/cxx/index_of_suffix.hpp"
#include"lang/cxx.hpp"
#include"memop/cast.hpp"
#include"mixc.hpp"
#include"utils/array.hpp"
#include"utils/memory.hpp"

namespace xuser{
    auto g_i                = uxx{};
    auto g_suffix           = seqptr<c08>{};
    auto g_buffer           = array<char, 4096>{};

    uxx foreach(){
        uxx total_lines = 0;

        dir{"."}.subdirs().foreach([&](asciis folder){
            dir{folder}.as_cwd();
            total_lines += foreach();
            dir{".."}.as_cwd();
        });

        dir{"."}.subfiles().foreach([&](asciis source){
            if (c08{source}.index_of_suffix(g_suffix) == not_exist){
                return;
            }

            uxx bytes = 0;
            uxx lines = 1; // 默认一行没有换行
            file item{source, access_mode_t::read_only};

            do{
                bytes = item.read<char>(g_buffer);
                lines += c08{asciis(g_buffer), bytes}.count_of('\n');
            } while(bytes == g_buffer->length);

            total_lines += lines;
            tty.write_line("\v | \v | lines:\v ", v{ ++g_i }.l(4), v{ source }.l(32), lines);
        });

        return total_lines;
    }

    xinit(the_main){
        if (env::args->length < uxx(2)){
            xhint("missing code full root path");
            return;
        }

        auto path = env::args[1];
        auto valid = xuser::dir{path}.as_cwd();
        xhint(path, valid);

        if (valid == bstate_t::fail){
            return;
        }

        auto total_lines = uxx{};
        auto default_type = make_array(c08(".c"), ".cpp", ".h", ".hpp");

        // main.exe $(pwd)  .c      .h
        // 参数1    参数2   参数3   参数4 ...
        if (env::args->length < uxx(3)){
            g_suffix = seqptr<c08>(default_type);
        }
        else{
            g_suffix = cast<seqptr<c08>>(env::args.backward(2));
        }

        total_lines = foreach();
        xhint(total_lines);
    };
}

